<!-- src/views/LogViewerPage.vue (最终真实数据版) -->
<template>
    <div class="log-viewer-layout">
        <!-- 左侧：日志文件列表 -->
        <div class="sidebar">
            <div class="sidebar-header">
                <h3>日志文件</h3>
                <el-button :icon="Refresh" circle @click="fetchLogFiles(1)" :loading="isFilesLoading" />
            </div>
            <div class="file-list" v-loading="isFilesLoading">
                <el-empty v-if="!logFiles.length && !isFilesLoading" description="没有找到日志文件" />
                <ul v-else>
                    <li v-for="file in logFiles" :key="file.key" :class="{ active: selectedFileKey === file.key }"
                        @click="selectFile(file.key)">
                        <div class="file-main-info"> <!-- 【新增】用一个div包裹文件名和信息 -->
                            <div class="file-name" :title="file.name">{{ file.name }}</div>
                            <div class="file-info">{{ file.date }} - {{ file.size }}</div>
                        </div>
                        <!-- 【核心新增】下载按钮 -->
                        <el-button :icon="Download" text circle class="download-btn"
                            @click.stop="handleDownloadLogFile(file)" />
                    </li>
                </ul>
            </div>
            <div class="pagination-container">
                <el-pagination size="small" layout="prev, pager, next" :total="fileTotal" :page-size="filePageSize"
                    :current-page="fileCurrentPage" @current-change="handleFilePageChange" />
            </div>
        </div>

        <!-- 右侧：日志详情 -->
        <div class="main-content" v-loading="isEntriesLoading">
            <div v-if="!selectedFileKey" class="placeholder">
                <el-empty description="请从左侧选择一个日志文件进行查看" />
            </div>
            <div v-else class="log-entries-container">
                <div class="content-header">
                    <h4>日志详情: <span class="selected-file-name" :title="selectedFileKey">{{ selectedFileKey }}</span>
                    </h4>
                </div>
                <el-table :data="logEntries" height="calc(100% - 120px)" stripe empty-text="此日志文件为空或无法解析">
                    <el-table-column prop="timestamp" label="时间" width="180" />
                    <el-table-column prop="remote_ip" label="来源IP" width="150" />
                    <el-table-column prop="operation" label="操作" width="180" show-overflow-tooltip />
                    <el-table-column prop="key" label="资源路径" show-overflow-tooltip />
                    <el-table-column prop="http_status" label="状态码" width="100" />
                    <el-table-column prop="error_code" label="错误码" width="120" />
                    <el-table-column prop="user_agent" label="User Agent" show-overflow-tooltip />
                </el-table>
                <div class="pagination-container">
                    <el-pagination background layout="total, prev, pager, next, jumper" :total="entryTotal"
                        :page-size="entryPageSize" :current-page="entryCurrentPage"
                        @current-change="handleEntryPageChange" />
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue';
import { Refresh, Search, Download } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { getBucketLoggingConfig, listLogFiles, readLogContent } from '@/api/logging.js';
import apiClient from '@/api';

const props = defineProps({
    bucketName: { type: String, required: true }
});

// 日志配置状态
const loggingConfig = ref({
    enabled: false,
    target_bucket: '',
    target_prefix: '',
});

// 左侧文件列表的状态
const isFilesLoading = ref(true);
const logFiles = ref([]);
const fileTotal = ref(0);
const filePageSize = ref(50);
const fileCurrentPage = ref(1);

// 右侧日志详情的状态
const isEntriesLoading = ref(false);
const selectedFileKey = ref(null);
const logEntries = ref([]);
const entryTotal = ref(0);
const entryPageSize = ref(50);
const entryCurrentPage = ref(1);

const fetchLogFiles = async (page = 1) => {
    if (!loggingConfig.value.enabled || !loggingConfig.value.target_bucket) {
        logFiles.value = [];
        fileTotal.value = 0;
        isFilesLoading.value = false;
        return;
    }
    isFilesLoading.value = true;
    fileCurrentPage.value = page;
    try {
        const res = await listLogFiles(
            loggingConfig.value.target_bucket,
            loggingConfig.value.target_prefix,
            fileCurrentPage.value,
            filePageSize.value
        );
        logFiles.value = res.data.items;
        fileTotal.value = res.data.total;
    } catch (error) {
        ElMessage.error('获取日志文件列表失败');
        console.error(error);
    } finally {
        isFilesLoading.value = false;
    }
};

const fetchLogEntries = async (page = 1) => {
    if (!selectedFileKey.value) return;
    isEntriesLoading.value = true;
    entryCurrentPage.value = page;
    try {
        const res = await readLogContent(
            loggingConfig.value.target_bucket,
            selectedFileKey.value,
            entryCurrentPage.value,
            entryPageSize.value
        );
        logEntries.value = res.data.items;
        entryTotal.value = res.data.total;
    } catch (error) {
        ElMessage.error('读取日志内容失败');
        console.error(error);
    } finally {
        isEntriesLoading.value = false;
    }
}

const selectFile = (fileKey) => {
    selectedFileKey.value = fileKey;
    // 切换文件时，重置到第一页并获取数据
    fetchLogEntries(1);
};

const handleFilePageChange = (page) => {
    fetchLogFiles(page);
};
const handleEntryPageChange = (page) => {
    fetchLogEntries(page);
};

const handleDownloadLogFile = (file) => {
    // 直接构造后端下载API的URL
    const downloadUrl = `${apiClient.defaults.baseURL}/api/v1/buckets/${loggingConfig.value.target_bucket}/logs/download?key=${encodeURIComponent(file.key)}`;

    // 利用浏览器原生功能发起下载
    window.location.href = downloadUrl;
};

// 页面加载时的入口逻辑
onMounted(async () => {
    try {
        const res = await getBucketLoggingConfig(props.bucketName);
        loggingConfig.value = res.data;
        // 获取到配置后，立即加载第一页的日志文件
        await fetchLogFiles(1);
    } catch (error) {
        ElMessage.error('获取日志配置失败');
        isFilesLoading.value = false;
    }
});
</script>

<style scoped>
/* 样式与之前版本相同，此处省略以保持简洁 */
.log-viewer-layout {
    display: flex;
    height: calc(100vh - 60px - 56px - 1px);
    background-color: #fff;
}

.sidebar {
    width: 320px;
    border-right: 1px solid #e0e0e0;
    display: flex;
    flex-direction: column;
}

.sidebar-header {
    padding: 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid #e0e0e0;
    flex-shrink: 0;
}

.file-list {
    flex-grow: 1;
    overflow-y: auto;
}

.file-list ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.file-list li {
    display: flex;
    justify-content: space-between;
    align-items: center;

    padding: 8px 16px;
    /* 调整内边距适应按钮 */
    cursor: pointer;
    border-bottom: 1px solid #f0f0f0;
}

.file-list li:hover {
    background-color: #f5f7fa;
}

.file-list li.active {
    background-color: #ecf5ff;
    border-right: 3px solid #409eff;
}

.file-main-info {
    /* 【新增】让文件名和信息部分可以收缩，避免挤压按钮 */
    flex-grow: 1;
    min-width: 0;
    /* flex布局中防止溢出的关键 */
}

.download-btn {
    /* 【新增】让按钮在flex布局中不收缩 */
    flex-shrink: 0;
    margin-left: 16px;
}

.file-name {
    font-weight: 500;
    color: #303133;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.file-info {
    font-size: 12px;
    color: #909399;
}

.pagination-container {
    padding: 8px;
    display: flex;
    justify-content: center;
    border-top: 1px solid #e0e0e0;
    flex-shrink: 0;
}

.main-content {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
}

.placeholder {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    color: #909399;
}

.log-entries-container {
    height: 100%;
    display: flex;
    flex-direction: column;
    padding: 16px;
}

.content-header {
    margin-bottom: 16px;
    flex-shrink: 0;
}

.selected-file-name {
    font-weight: normal;
    color: #606266;
}
</style>